﻿using Furion.DatabaseAccessor;
using Furion.DataEncryption;
using Furion.DependencyInjection;
using Furion.FriendlyException;
using HiSport.Application.System.User.Dtos;
using HiSport.Core;
using HiSport.Core.Const;
using HiSport.Core.Entity;
using HiSport.Core.Enum;
using Mapster;
using SqlSugar;
using Yitter.IdGenerator;

namespace HiSport.Application.System.User.Service
{
    public class UserService : ITransient, IUserService
    {
        public readonly ISqlSugarClient _dbContext;

        public UserService(ISqlSugarClient dbContext)
        {
            _dbContext = dbContext;
        }

        /// <summary>
        /// 获取用户分页列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedList<SysUser>> Page(PageUserInput input)
        {
            RefAsync<int> total = 0;
            var list = await _dbContext.Queryable<SysUser>()
                .WhereIF(!string.IsNullOrWhiteSpace(input.Account), u => u.Account.Contains(input.Account))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Phone), u => u.Phone.Contains(input.Phone))
                .ToPageListAsync(input.PageIndex, input.PageSize, total);

            return new PagedList<SysUser>
            {
                Items = list,
                PageIndex = input.PageIndex,
                PageSize = input.PageSize,
                TotalCount = total
            };

        }

        /// <summary>
        /// 增加用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> AddUser(AddUserInput input)
        {
            try
            {
                _dbContext.Ado.BeginTran();

                input.Id = YitIdHelper.NextId();
                var isExist = await _dbContext.Queryable<SysUser>().Filter(null, true).AnyAsync(u => u.Account == input.Account);
                if (isExist) throw Oops.Oh(ErrorCodeEnum.D1003);
                var password = MD5Encryption.Encrypt(CommonConst.SysPassword);
                input.Password = password;
                var user = input.Adapt<SysUser>();


                //添加用户
                var res = await _dbContext.Insertable(user).ExecuteCommandAsync();

                //增加 角色和组织集
                _dbContext.Ado.CommitTran();
                return res > 0;
            }
            catch (Exception ex)
            {
                _dbContext.Ado.RollbackTran();
                throw Oops.Oh(ex);
            }


        }

        /// <summary>
        /// 更新用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> UpdateUser(UpdateUserInput input)
        {
            try
            {
                _dbContext.Ado.BeginTran();

                if (await _dbContext.Queryable<SysUser>().Filter(null, true).AnyAsync(u => u.Account == input.Account && u.Id != input.Id))
                    throw Oops.Oh(ErrorCodeEnum.D1003);

                var res = await _dbContext.Updateable(input.Adapt<SysUser>()).IgnoreColumns(true)
                      .IgnoreColumns(u => new { u.AccountType, u.Password, u.Status }).ExecuteCommandAsync();

                //修改 角色和组织集

                _dbContext.Ado.CommitTran();
                return res > 0;
            }
            catch (Exception ex)
            {
                _dbContext.Ado.RollbackTran();
                throw Oops.Oh(ex);
            }

        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> DeleteUser(Entity input)
        {
            var user = await _dbContext.Queryable<SysUser>().FirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
            if (user.AccountType == AccountTypeEnum.SuperAdmin)
                throw Oops.Oh(ErrorCodeEnum.D1014);
            if (user.Id == CurrentUser.UserId)
                throw Oops.Oh(ErrorCodeEnum.D1001);

            try
            {
                _dbContext.Ado.BeginTran();

                var res = await _dbContext.Deleteable(user).ExecuteCommandAsync();

                // 删除用户角色

                // 删除用户扩展机构

                _dbContext.Ado.CommitTran();
                return res > 0;
            }
            catch (Exception ex)
            {
                _dbContext.Ado.RollbackTran();
                throw Oops.Oh(ex);
            }
        }

    }
}
